﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using SqlSugar;
using System.IdentityModel.Tokens.Jwt;
using System.Net;
using System.Security.Principal;
using System.Text;
using VueAdminService.DTO;
using VueAdminService.Utils;
using VueAdminService.VO;

namespace VueAdminService.Attributes
{
	/// <summary>
	/// 统一验证token的拦截器
	/// 按需配置（Action、Controler或全局）
	/// </summary>
	public class TokenRequiredAttribute : ActionFilterAttribute
	{
		public TokenRequiredAttribute() { }
		/// <summary>
		/// 在Action方法执行前触发
		/// </summary>
		/// <param name="context"></param>
		public override void OnActionExecuting(ActionExecutingContext context)
		{
			var result = new JsonResult(null);
			if (context.HttpContext.Request.Headers.ContainsKey("token"))
			{
				var token = context.HttpContext.Request.Headers["token"];
				if (string.IsNullOrWhiteSpace(token))
				{
					result.StatusCode = (int)ResponseCode.Unauthorized;
					result.Value = "登陆信息不存在,请先登陆";
					context.Result = result;// new JsonResult(ResponseResult<bool>.Result(ResponseCode.Unauthorized, "登陆信息不存在,请先登陆", false));
					return;
				}

				//TODO 校验token有效性
				string? userId = TokenUtil.GetValueFromJwtToken(token, "sub");
				DateTime exp = DateTime.UnixEpoch.AddSeconds(long.Parse(TokenUtil.GetValueFromJwtToken(token, "exp"))).AddHours(8);
				if (DateTime.Now >= exp)
				{//token已过期
					result.StatusCode = (int)ResponseCode.Forbidden;
					result.Value = "登陆信息已过期,请重新登陆";
					context.Result = result; // new JsonResult(ResponseResult<bool>.Result(ResponseCode.Forbidden, "登陆信息已过期,请重新登陆", false));
					return;
				}
				ISqlSugarClient db = context.HttpContext.RequestServices.GetService<ISqlSugarClient>();
				var user = db.Queryable<UserDTO>().First(o => o.UserId == userId);
				if (user == null)
				{
					result.StatusCode = (int)ResponseCode.Forbidden;
					result.Value = "登陆信息不存在,请重新登陆";
					context.Result = result;// new JsonResult(ResponseResult<bool>.Result(ResponseCode.Forbidden, "登陆信息不存在,请重新登陆", false));
					return;
				}
				//需要根据数据字典判断用户状态并给出相应提示
				var config = context.HttpContext.RequestServices.GetService<IConfiguration>();
				string? rejectStatus = config.GetValue<string>("AppConfig:RejectLoginUserStatus");
				if (string.IsNullOrWhiteSpace(rejectStatus) && rejectStatus.Split(",").Contains(user.Status))
				{
					result.StatusCode = (int)ResponseCode.NotAcceptable;
					result.Value = "该用户禁止访问，请与管理员联系";
					context.Result = result;//new JsonResult(ResponseResult<bool>.Result(ResponseCode.Forbidden, "禁止访问", false));
					return;
				}
				base.OnActionExecuting(context);

			}
			else
			{
				result.StatusCode = (int)ResponseCode.Unauthorized;
				result.Value = "登陆信息不存在,请先登陆";
				context.Result = result;//new JsonResult(ResponseResult<bool>.Result(ResponseCode.Unauthorized, "登陆信息不存在,请先登陆", false));
				return;
			}
		}

		// 在Action方法执行后触发
		public override void OnActionExecuted(ActionExecutedContext context)
		{

		}

		// 在Result返回前触发
		public override void OnResultExecuting(ResultExecutingContext context)
		{

		}

		// 在Result返回后触发
		public override void OnResultExecuted(ResultExecutedContext context)
		{

		}
	}

}
